package com.wtwd.campus.hxy.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import com.wtwd.campus.hxy.constant.RespCode;
import com.wtwd.campus.hxy.model.entity.HxyFence;
import com.wtwd.campus.hxy.model.entity.HxyStudent;
import com.wtwd.campus.hxy.model.vo.LocationVO;
import com.wtwd.campus.hxy.model.vo.ResultVO;
import com.wtwd.campus.hxy.service.DeviceService;
import com.wtwd.campus.hxy.service.HxyPhoneService;
import com.wtwd.campus.hxy.service.HxyFenceService;
import com.wtwd.campus.utils.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author zdl
 * @Description
 * @create 2021-07-26 13:47
 */
@Api(tags = "设备管理")
@RestController
@RequestMapping("/hxy/device")
public class HxyDeviceController {

    private final static Logger log = LoggerFactory.getLogger(HxyDeviceController.class);

    @Resource
    private DeviceService deviceService;
    @Autowired
    private HxyFenceService fenceService;
    @Resource
    private CommandSendUtils commandSendUtils;
    @Autowired
    private PushUtils pushUtils;

    @ApiOperation("获取当前位置")
    @DynamicParameters(name = "getLocationModel", properties = {
            @DynamicParameter(name = "imei", value = "学校ID", dataTypeClass = String.class, required = true)
//            , @DynamicParameter(name = "beginTime", value = "开始时间", dataTypeClass = String.class, required = true)
//            , @DynamicParameter(name = "endTime", value = "结束时间", dataTypeClass = String.class, required = true)
    })
    @ApiResponses({@ApiResponse(code = 400, message = "参数错误")})
    @PostMapping("/getLocation")
    public ResultVO getLocation(@RequestBody JSONObject getLocationModel) {
        String imei = getLocationModel.getString("imei");
        LocationVO location = deviceService.getLastLocationByImei(imei);
        if(location == null){
            return ResultVO.error(RespCode.NO_MESSAGE);
        }
        long uploadTime = Long.valueOf(location.getUploadTime());
        location.setUploadTime(DateUtils.format(new Date(uploadTime), DateUtils.dateFormat4));
        return ResultVO.ok(location);
    }

    @ApiOperation("获取学生轨迹")
    @DynamicParameters(name = "queryTrackModel", properties = {
            @DynamicParameter(name = "imei", value = "学校ID", dataTypeClass = String.class, required = true)
            , @DynamicParameter(name = "beginTime", value = "开始时间", dataTypeClass = String.class, required = true)
            , @DynamicParameter(name = "endTime", value = "结束时间", dataTypeClass = String.class, required = true)
    })
    @ApiResponses({@ApiResponse(code = 400, message = "参数错误")})
    @PostMapping("/getTrack")
    public ResultVO getTrack(@RequestBody JSONObject queryTrackModel) {
        String imei = queryTrackModel.getString("imei");
        String beginTime = queryTrackModel.getString("beginTime");
        String endTime = queryTrackModel.getString("endTime");
        if (StringUtils.isAnyBlank(imei, beginTime, endTime)) {
            return ResultVO.error(RespCode.PARAMS_ERROR);
        }
        return ResultVO.ok(deviceService.getTrackByImeiAndTime(imei,
                DateUtils.getTimestamp(beginTime), DateUtils.getTimestamp(endTime)));
    }

    @ApiOperation("绑定设备")
    @DynamicParameters(name = "bindModel", properties = {
            @DynamicParameter(name = "studentId", value = "学生ID", dataTypeClass = String.class, required = true)
            , @DynamicParameter(name = "studentNo", value = "学号", dataTypeClass = String.class, required = true)
            , @DynamicParameter(name = "studentName", value = "学生名称", dataTypeClass = String.class, required = true)
            , @DynamicParameter(name = "imei", value = "IMEI", dataTypeClass = String.class, required = true)
    })
    @ApiResponses({@ApiResponse(code = 400, message = "参数错误")})
    @PostMapping("/bind")
    public Object bind(@RequestBody JSONObject bindModel) {
        HxyStudent student = JSONObject.toJavaObject(bindModel, HxyStudent.class);
        return deviceService.bind(student);
    }

    /**
     *
     *
     * @param unbindModel
     * @return
     */
    @ApiOperation("解除绑定设备")
    @DynamicParameters(name = "unbindModel", properties = {
            @DynamicParameter(name = "operateTime", value = "解绑时间", dataTypeClass = String.class, required = true)
            , @DynamicParameter(name = "imei", value = "IMEI", dataTypeClass = String.class, required = true)
    })
    @ApiResponses({@ApiResponse(code = 400, message = "参数错误")})
    @PostMapping("/unbind")
    public ResultVO unbind(@RequestBody JSONObject unbindModel) {
        String imei = unbindModel.getString("imei");
        if (!commandSendUtils.deviceOnline(imei)) {
            return ResultVO.error(RespCode.DEVICE_OFFLINE);
        }else{
            ResultVO resultVO = deviceService.unbind(imei);
            if (resultVO.getCode() == RespCode.SUCCESS.getCode()) {
                log.info("设备[{}],已解绑,操作时间:{}", imei, unbindModel.getString("operateTime"));
                boolean isSend = commandSendUtils.reSetDevice(imei, CommandNumberUtil.getCurTime(),true,-3,false);
                if(!isSend){
                    return ResultVO.error(RespCode.FAIL);
                }
            }
            return resultVO;
        }
    }

    @ApiOperation("电子围栏增删改")
    @DynamicParameters(name = "fenceModel", properties = {
            @DynamicParameter(name = "type", value = "操作类型", dataTypeClass = Integer.class, required = true, example = "1 增加2 删除，3 修改")
            , @DynamicParameter(name = "imei", value = "IMEI", dataTypeClass = String.class, required = true)
            , @DynamicParameter(name = "fenceId", value = "围栏ID", dataTypeClass = String.class, example = "type=1时,可为空")
            , @DynamicParameter(name = "name", value = "围栏名称", dataTypeClass = String.class, required = true)
            , @DynamicParameter(name = "radius", value = "半径", dataTypeClass = String.class, required = true)
            , @DynamicParameter(name = "fenceType", value = "围栏类型", dataTypeClass = String.class, required = true, example = "0进围栏,1出围栏")
            , @DynamicParameter(name = "longitude", value = "经度", dataTypeClass = Float.class, required = true)
            , @DynamicParameter(name = "latitude", value = "纬度", dataTypeClass = Float.class, required = true)
            , @DynamicParameter(name = "timeperiod", value = "报警时段", dataTypeClass = ArrayList.class, required = true)
    })
    @ApiResponses({@ApiResponse(code = 400, message = "参数错误")})
    @PostMapping("/fenceCUD")
    public Object fence(@RequestBody JSONObject fenceModel) {
        HxyFence fence = JSONObject.toJavaObject(fenceModel, HxyFence.class);
        // 经纬度转换
        double[] doubles = GPSUtils.gcj02_To_Gps84(Double.parseDouble(fence.getLatitude()), Double.parseDouble(fence.getLongitude()));
        fence.setLatitude(String.valueOf(doubles[0]));
        fence.setLongitude(String.valueOf(doubles[1]));
        JSONArray timeperiod = fenceModel.getJSONArray("timeperiod");
        if (timeperiod != null) {
            fence.setTimeperiod(timeperiod.toJSONString());
        }
        switch (fenceModel.getInteger("type")) {
            case 1:
                fenceService.save(fence);
                break;
            case 2:
                fenceService.delete(fence.getFenceId());
                break;
            case 3:
                fenceService.updateByKey(fence);
                break;
            default:
                return ResultVO.error(RespCode.PARAMS_ERROR);
        }
        HashMap<String, String> map = new HashMap<>();
        map.put("fenceId", fence.getFenceId());
        map.put("code","0");
        map.put("message","操作成功");
        return map;
    }

    @ApiOperation("电子围栏查询")
    @DynamicParameters(name = "queryFenceModel", properties = {
            @DynamicParameter(name = "imei", value = "IMEI", dataTypeClass = String.class, required = true)
    })
    @ApiResponses({@ApiResponse(code = 400, message = "参数错误")})
    @PostMapping("/queryFence")
    public ResultVO queryfence(@RequestBody JSONObject queryFenceModel) throws IllegalAccessException {
        String imei = queryFenceModel.getString("imei");
        List<HxyFence> fenceList = fenceService.getFenceByImei(imei);
        List<Map<String, Object>> resultList = parseTimePeriod(fenceList);
        return ResultVO.ok(resultList);
    }

    /**
     * 远程关机
     * @param jsonObject
     * @return
     */
    @PostMapping("/remoteShutDown")
    public Object remoteShutDown(@RequestBody JSONObject jsonObject){
        String imei = jsonObject.getString("imei");
        int type = jsonObject.getInteger("type");
        String operateTime = jsonObject.getString("operateTime");
        boolean isOnline = commandSendUtils.deviceOnline(imei);
        if(!isOnline){
            return ResultVO.error(RespCode.DEVICE_OFFLINE);
        }
        boolean isSend = commandSendUtils.shutDownDevice(imei,CommandNumberUtil.getCurTime(),-3);
        if(isSend) pushUtils.pushHxyShutDown(imei,DateUtils.format(new Date(),DateUtils.dateFormat4));
        return isSend ? ResultVO.okWithOutData() : ResultVO.error(RespCode.FAIL);
    }

    /**
     * 立即定位
     * @param jsonObject
     * @return
     */
    @PostMapping("/locateNow")
    public Object locateNow(@RequestBody JSONObject jsonObject){
        String imei = jsonObject.getString("imei");
        boolean isOnline = commandSendUtils.deviceOnline(imei);
        if(!isOnline){
            return ResultVO.error(RespCode.DEVICE_OFFLINE);
        }
        boolean isSend = commandSendUtils.queryDeviceLocation(imei,CommandNumberUtil.getCurTime(),-3,true,false);
        return isSend ? ResultVO.okWithOutData() : ResultVO.error(RespCode.FAIL);
    }


    public List<Map<String,Object>> parseTimePeriod(List<HxyFence> hxyFenceList) throws IllegalAccessException {
        List<Map<String,Object>> resultList = new ArrayList<>();
        for(HxyFence hxyFence : hxyFenceList){
            Class<?> clazz = hxyFence.getClass();
            Map<String,Object> map = new HashMap<>();
            for (Field field : clazz.getDeclaredFields()) {
                field.setAccessible(true);
                String fieldName = field.getName();
                Object value = (Object)field.get(hxyFence);
                // 时间段转成数组
                if(fieldName.equals("timeperiod")){
                    JSONArray jsonArray = JSONArray.parseArray(hxyFence.getTimeperiod());
                    map.put("timeperiod",jsonArray);
                }else if(fieldName.equals("serialVersionUID")){
                }else{
                    map.put(fieldName,value);
                }
            }
            resultList.add(map);
        }
        return resultList;
    }

    public static void main(String[] args) {
        String encode = MD5Utils.encode("0IrxHqSWJoIulR8Ro0yiM0Qo7qV16qQv" + "jyZG83lNv2bg4KRReKJp9iVVV2WEbsPV" + "12616145448");
        System.out.println(encode);
    }
}
